/**
 * 
 */
package com.et114.components.acegi.vote;

import org.acegisecurity.Authentication;
import org.acegisecurity.ConfigAttribute;
import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.vote.AccessDecisionVoter;
import org.acegisecurity.GrantedAuthority;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache;

import java.util.Iterator;

import com.et114.components.acegi.Constants;
/*
 * @author guanhw
 */
public class GRoleVoter implements AccessDecisionVoter {
	private Log						logger		= LogFactory.getLog ( this.getClass ( ) );
	private String					rolePrefix	= Constants.VOTER_ROLE_PREFIX;
	private EhCacheBasedUserCache	userCache;
	
	private boolean					withCache = true;
	/**
	 * 
	 */
	public GRoleVoter ( ) {
		// TODO Auto-generated constructor stub
	}
	// ~ Instance fields
	// ================================================================================================

	

	// ~ Methods
	// ========================================================================================================

	public String getRolePrefix() {
		return rolePrefix;
	}

	public void setUserCache ( EhCacheBasedUserCache userCache ) {
		this.userCache = userCache;
	}

	/**
	 */
	public void setRolePrefix(String rolePrefix) {
		Assert.notNull( rolePrefix , "rolePrefix must not be null" );
		Constants.VOTER_ROLE_PREFIX = rolePrefix ;
		this.rolePrefix = rolePrefix;
	}

	public boolean supports(ConfigAttribute attribute) {
		if ((attribute.getAttribute() != null) && attribute.getAttribute().startsWith(getRolePrefix())) {
			return true;
		}
		else {
			return false;
		}
	}

	/**
	 */
	public boolean supports(Class clazz) {
		return true;
	}

	public int vote( Authentication authentication, Object object, ConfigAttributeDefinition config ) {
		logger.debug(  "进入role 角色投票器！！！"  ) ;
		int result = ACCESS_ABSTAIN;
		GrantedAuthority[] userGas = new GrantedAuthority[ 0 ]  ; 
		if ( withCache ) {
			if ( userCache.getUserFromCache ( authentication.getName ( ) ) == null ) return ACCESS_ABSTAIN ;
			userGas = userCache.getUserFromCache ( authentication.getName ( ) ).getAuthorities ( ) ;
		}
		else {
			userGas = authentication.getAuthorities ( ) ;				
		}
		if ( userGas.length == 0  ) {
			userGas = new GrantedAuthority [ 1 ];
			userGas [ 0 ] = new GrantedAuthorityImpl (
					Constants.VOTER_USER_PREFIX );				
		}				
		
		 
		if ( logger.isDebugEnabled ( ) ) {
			for (int i = 0; i < userGas.length; i++) {
				logger.debug( "当前用户" + authentication.getName() + "..............." + userGas [ i ].getAuthority() ) ;
			}
		}
		
		
		Iterator iter = config.getConfigAttributes();

		while (iter.hasNext()) {
			ConfigAttribute attribute = (ConfigAttribute) iter.next();

			if ( this.supports ( attribute ) ) {
				result = ACCESS_DENIED;
				if ( logger.isDebugEnabled ( ) ) 
					logger.debug(  "has.." +  authentication.getName()  + " must has.. " + attribute.getAttribute()   ) ; 
				
				// Attempt to find a matching granted authority
				for ( int i = 0 ; i < userGas.length ; i ++ ) {
					if (attribute.getAttribute().equals( userGas[i].getAuthority() ) ) {
						return ACCESS_GRANTED;
					}
				}
			}
		}
		logger.debug(  "当前角色：" +  authentication.getName()  + " 投票结果： " + result   ) ; 
		return result;
	}

	public boolean getWithCache ( ) {
		return withCache;
	}

	public void setWithCache ( boolean withCache ) {
		this.withCache = withCache;
	}
}
